from fastapi import Request
from pydantic import BaseModel
from tortoise.transactions import atomic, in_transaction

from service import RepositoryService, UserService, CollaboratorService, BookService
from common.result.Result import Result
from common.enum import BaseEnum
from common.const import BaseConstant
from util.str import Str
from util.log import Log
from util.token import Token
from util.time import Time
from util.redis import Redis

async def GetBookTree(req: Request, repositoryShortUri: str):
    try:
        if Str.isBlank(repositoryShortUri):
            Log.error('参数为空，检查参数')
            return Result.error(BaseEnum.PARAMETER_INVALID_ERROR)
        
        
        repository = await RepositoryService.getRepositoryByShortUri(repositoryShortUri)
        if repository == None:
            Log.error('repository 不存在')
            return Result.error(BaseEnum.REPOSITORY_NOT_EXISTS_ERROR)
        
        token = req.headers.get("token")
        user = await UserService.getUserByToken(token)

        # 判断仓库是否允许用户读
        flag = await RepositoryService.getUserReadPermission(repository, user.id if user else 0)
        if flag == False:
            Log.error('该 repository 不允许该用户读')
            return Result.error(BaseEnum.REPOSITORY_NO_READ_PERMISSION_ERROR)

        # 取缓存
        key = BaseConstant.BOOK_TREE_KEY % repositoryShortUri
        result = Redis.getItem(key)
        if result != None:
            return Result.success(result.get("bookTree"))
        
        # 构造 树型 结构
        bookList = await BookService.getBookListByRepositoryId(repository.id)
        result = await bookTree(bookList)

        # 
        Redis.setItem(key, {
            "bookTree": result
        }, 60 * 60 * 2)

        return Result.success(result)
    except Exception as e:
        Log.error('获取 book 的树形数据异常', e)
        return Result.error(BaseEnum.SERVICE_ERROR)

from models.book import Book
from typing import List
async def bookTree(bookList: List[Book], parentId: int = 0):
    try:
        result = []
        for item in bookList:
            if item.parent_id == parentId:
                result.append({
                    "id": item.id,
                    "shortUri": item.short_uri,
                    "label": item.title,
                    "showAppend": False,
                    "sortOrder": item.sort_order,
                    "updateTime": item.update_time,
                    "children": await bookTree(bookList, item.id)
                })
        result = sorted(result, key=lambda item: (item['sortOrder'], -item['updateTime'].timestamp()), reverse=False)
        return result
    except Exception as e:
        Log.error('构造 book 树形数据异常', e)